require "lfs"
require "unity"
local MPIModel = require "MPIModel"
local CreateRadome = require "luaCreateRadome"
local nl = require"luaNumeric"
local QGallop = require"QGMainWindow"
require "Q2DViewer"
local Q2DViewer = require "Q2DViewerEx"


----------------------------------------------------------------------------
--初始化参数
local FSSRadomeDMGenerator={
	console_mode = false;
	p = 15; --频选周期
	nx = {20,40,60};
	xstart=500;
	xend=100;	

	create_str = [[
	
	
local nl = require'luaNumeric'
w1,w2 = 1.2901,0.5743;
l1,l2 = 2.0653,1.9104;
dx = 6.5
dy = dx/2/math.sqrt(3);

w1,w2 = 2.6,1.2;
l1,l2 = 4,3.8;
dx = 14.5
dy = dx/2/math.sqrt(3);

p = dy*2;                       --频选周期
nx = {20,40,60,80,100,120,140,160,220,240,260,280,300};          --分割节点
nx = {120};          --分割节点
xstart=1500;            --贴敷起始位置
xend=100;               --贴敷结束位置

function rot_array(shape)
	local s1 = shape:copy();
	local s2 = shape:copy();
	s1:rotate(zAxis,120);
	s2:rotate(zAxis,240);
	return Geometry.join({shape,s1,s2});
end

function gen_yunit( w1, w2,l1,l2)
	local h=1
	local l11 = w1/2;
	local l21 = w2/2;
	local outer = Geometry.create_rect( {pt1={-w1/2,0},pt2={w1/2,l11+l2} });
	local inner = Geometry.create_rect( {pt1={-w2/2,0},pt2={w2/2,l21+l2} });	
	local inner = rot_array(inner);
	local outer = rot_array(outer);
	local all = Geometry.difference({outer,inner});
	all:rotate(zAxis,90)
	return all:copy();
end
	
function gen_cunit( r1,r2)
	
	local outer = Geometry.create_circle( {radius=r1 });
	local inner = Geometry.create_circle( {radius=r2 });
	local all = Geometry.difference({outer,inner});
	return all:copy();
end
function gen_liu_bian_xing( r1)
	pts={}
	for ii=1,6 do 
		table.insert(pts,{r1*math.sin(pi/3*ii),r1*math.cos(pi/3*ii),0})
	end
	return pts
end

function gen_liuunit( r1,r2)	
	local pts1 = gen_liu_bian_xing ( r1 );
	local pts2 = gen_liu_bian_xing ( r2 );

	local outer = Geometry.NewPolygonFromPts({     name="poly",
								pts=pts1,  --顶点
								fill_color = {0,1,0.8}, 
							});

	local inner = Geometry.NewPolygonFromPts({     name="poly",
								pts=pts2,  --顶点
								fill_color = {0,1,0.8}, 
							});

	local all = Geometry.difference({outer,inner});
	return all:copy();
end

unitGenerator = function( x,y,z)
	local w=2;
	local l = 10;
	local dw = 0.5;
	return gen_liuunit (4,2.5)
end;

GLShapes = require"luaGLShapes";

--mmm = GLShapes.load_step('d:\temp\m.step');	
extUnitGenerator = function( x,y,z)
	return GLShapes.NewCylinder( {radius=3;height=2; } )
	--return mmm;
end;	
extUnitGenerator(0,0,0);



	
	]];
	
	set_settings_str = Gallop.set_settings_str;
	get_settings_str = Gallop.get_settings_str;
};
-----------------------------------------------------------------------------


-----------------------------------------------------------------------------
---[[创建表和创建元表
function FSSRadomeDMGenerator:new (o)
	o = o or {};
	self.__index = self;	
	setmetatable(o,self)
	o:regist_funcs_to_gallop();
	o.init_strs = o:get_settings_str();
	return o;
end
--]]---------------------------------------------------------------------------


----------------------------------------------------------------------------------------------------------------------------------------
--注册全局函数
function FSSRadomeDMGenerator:regist_funcs_to_gallop()
	Gallop.init_funcs['FSSRadomeDMGenerator'] = function()
		local str = self.init_strs;
		assert( type('str')=='string', 'FSS DM Generator, init string error' );
		if str ~= '' then
			Geometry.RCWASolver:set_settings_str(str)
		end
		if str ~= '' then
			Geometry.FSSRadomeDMGenerator:set_settings_str(str)
		end
		Geometry.FSSRadomeDMGenerator:update_script_to_ui();
	end;
	
	Gallop.load_funcs['FSSRadomeDMGenerator'] = function()
		local str = Geometry.get_setting( 'FSSRadomeDMGenerator.Settings' )
		if str ~= '' then
			Geometry.FSSRadomeDMGenerator:set_settings_str(str)
		end
		Geometry.FSSRadomeDMGenerator:update_script_to_ui();
	end;
	
	Gallop.presave_funcs['FSSRadomeDMGenerator'] = function()
		Geometry.FSSRadomeDMGenerator:update_script_from_ui()
		local str = Geometry.FSSRadomeDMGenerator:get_settings_str();
		Geometry.set_setting( 'FSSRadomeDMGenerator.Settings', str );
	end;
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--GUI交互函数
function FSSRadomeDMGenerator:update_script_to_ui()
end

function FSSRadomeDMGenerator:update_script_from_ui()
end
----------------------------------------------------------------------------------------------------------------------------------------



function FSSRadomeDMGenerator:create_viewer2D ( )
	return viewer;
end



----------------------------------------------------------------------------------------------------------------------------------------
--运行
function FSSRadomeDMGenerator:perspective_view ()
	-- print('perspective')
	if self.console_mode == false then
		local QGallop = require"QGMainWindow"
		if QGallop~=nil and QGallop.getMainWindow then
			local mw = QGallop.getMainWindow();
			if mw~=nil then
				local view = mw:get3DView();
				if view~=nil then
					view:showEntireScene();
					view:perspective();
				end
			end
		end
	end
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--设置计算脚本
function FSSRadomeDMGenerator:set_script(script)
	if script ~= self.create_str then
		self.create_str = script;
		 print(self.create_str);
		self:create_model_from_str();
		self:update_script_to_ui();
	end	
end
----------------------------------------------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------------------------------------------------------------
--设置计算脚本
function FSSRadomeDMGenerator:create_model_from_str()

     local f = load(self.create_str)
      f();
       
      print( p,nx,xstart,xend,unitGenerator,extUnitGenerator)
      self.p = p;      
      self.nx = nx;
      self.xstart = xstart;
      self.xend = xend;
      self.unitGenerator = unitGenerator;
      
     self.extUnitGenerator = extUnitGenerator;
    --debug.sethook(trace, "l")
end
----------------------------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------
--导入模型
function FSSRadomeDMGenerator:load ( path )
	Geometry.clear_all();
	self.path = path;
	self.radome = Geometry.load_step(path);
	-- Geometry.AddShape(self.radome)
	self:perspective_view()
	print(path)
	
	-----------------------------------------------------
	-- import the radome model
	self.analyzer = CreateRadome.RadomeDMAnalyzer:new();
	assert(self.analyzer:import_from_file(path)>=0, "import file error!\n"..path );
	-- assert(analyzer:isSolid(), "导入模型不包含实体!" );
	assert(self.analyzer:numSolid()<=1, "导入模型超过一个实体!" );
	assert(self.analyzer:checkOrientation(), " 天线罩大端未朝向x轴正向" );
	assert(self.analyzer:decomposite(), " 天线罩面元分析失败！" );
	-- assert(analyzer:decomposite_semi_radome(), " 天线罩面元分析失败！" );
	self.analyzer:intersection_with_xy_plane()
	-- assert(analyzer:regenerate_profile(), "重新生成外表面错误" );
	-- assert(analyzer:regenerate_from_xz_section(), "重新生成外表面错误" );
	-----------------------------------------------------

	self:perspective_view()
end
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------
--创建锥罩频选结构
function FSSRadomeDMGenerator:generate_outer ( )
		

end
-----------------------------------------------------------------------------

function FSSRadomeDMGenerator:create_cone_fss ( )

	self:update_script_from_ui();
	self:create_model_from_str();
	
	print("创建频选结构...");
	print("  周期："..self.p);
	print("  频选开始位置："..self.xstart);
	print("  频选结束位置："..self.xend);
	print("  分段数量："..#self.nx);
	 
	local nxsplit = nl.new_ivector( #self.nx )
	for ii=1,#self.nx do
	     nxsplit[ii] = self.nx[ii];
	end
	
	local  tsplit = nl.new_vector();
	-- tsplit :push_back(0);
	-- tsplit :push_back(math.pi/2);

	self.generator = CreateRadome.FSSRadomeDMGenerator:new(self.p,1e-4);
	self.generator:fss_range(self.xstart,self.xend)
	self.generator:fss_theta_range(0,math.pi)
	-- self.generator:setDn(self.dN or 20)
	self.generator:create_outer( self.analyzer );
	
	assert(self.generator:build_equal_segments_pts_from_curve()>=0, "生成U轴关键点失败");


	self.generator:split_face_by_period_ndoes(nxsplit,tsplit);	
	
	self.generator:unitGenerator(self.unitGenerator);
	self.generator:extUnitGenerator(self.extUnitGenerator);

---[[	


	self.generator:build_fss_units();
	--self.generator:build_external_units();
--]]

	self.generator:write_fss( self.path .. "-fss.stp" );
	--self.generator:write_cfss( self.path .. "-cfss.stp" );
	--self.generator:write_combined_fss( self.path .. "-all.stp" );
	--self.generator:write_fss_segments( self.path .. "-fss-segments(%d).stp" );
	--self.generator:write_cfss_segments( self.path .. "-cfss-segments(%d).stp" );
end

function FSSRadomeDMGenerator:create_cone_fss ( )
	self:update_script_from_ui();
	self:create_model_from_str();
	
	nl.num_threads(64)
	
	print("创建频选结构...");
	print("  周期："..self.p);
	print("  频选开始位置："..self.xstart);
	print("  频选结束位置："..self.xend);
	print("  分段数量："..#self.nx);
	 
	local nxsplit = nl.new_ivector( #self.nx )
	for ii=1,#self.nx do
	     nxsplit[ii] = self.nx[ii];
	end
	print(nxsplit)
	
	local  tsplit = nl.new_vector();
	-- tsplit :push_back(0);
	-- tsplit :push_back(math.pi/2);

	self.generator = CreateRadome.FSSRadomeDMGenerator:new(self.p,1e-4);
	self.generator:fss_range(self.xstart,self.xend)
	self.generator:fss_theta_range(0,math.pi)
	-- self.generator:setDn(self.dN or 20)
	self.generator:create_outer( self.analyzer );
	
	assert(self.generator:build_equal_segments_pts_from_curve()>=0, "生成U轴关键点失败");

	self:perspective_view()

	self.generator:split_face_by_period_ndoes(nxsplit,tsplit);	
	
	self.generator:unitGenerator(self.unitGenerator);
	self.generator:extUnitGenerator(self.extUnitGenerator);
--[[

	pp = self.p * nl.sqrt(3)/2.0;
	--self.generator:create_create_start_edge();
	--self.generator:deform_create_start_edge();
	--self.generator:create_section_edges();
	self.generator:create_start_edge();

	
	shape1,shape2 = self.generator:generated_edges();
	shape1:name('sec edge');
	shape2:name('sec semi edge');
	Geometry.AddShape(shape1:copy());
	Geometry.AddShape(shape2:copy());
	
	self.generator:deform_start_edge(0,70);
	--self.generator:deform_start_edge(0,0);
	--self.generator:deform_start_edge(0,20);
	shape1,shape2 = self.generator:generated_edges();
	shape1:name('start edge');
	shape2:name('start semi edge');
	Geometry.AddShape(shape1:copy());
	Geometry.AddShape(shape2:copy());
	--for ii=1,30 do 
	for ii=1,120 do 
		self.generator:deform_start_edge(pp,pp);
		--shape = self.generator:generated_edge();
		--shape:name('deform edge'..ii);
		--Geometry.AddShape(shape:copy());
		Geometry.synchronize();
		shape1,shape2 = self.generator:generated_edges();
		shape1:name('deform edge');
		shape2:name('deform semi edge');
		Geometry.AddShape(shape1:copy());
		Geometry.AddShape(shape2:copy());
	end
	self.generator:create_section_points();
	Geometry.synchronize();
	self.generator:build_fss_units();
	
	print('mirror solids..')
	self.generator:mirro_solids_zx();
	print('mirror solids finished')
	
	self.generator:write_fss_solid( self.path .. "-fss-solids.stp" );
	self.generator:write_fss_mirror_solid( self.path .. "-fss-mirror-solids.stp" );
	
	self.generator:generate_cfss_surface()
	
	self.generator:create_mesh(8,false,false,false,true);
	self.generator:export_mesh( self.path .. "-cfss-mesh.stl" );
	
	self.generator:post_build_fss_units();
	self.generator:write_fss( self.path .. "-fss.stp" );
	self.generator:write_cfss( self.path .. "-cfss.stp" );

	--self.generator:create_mesh(8,true,true,true);
--]]
end


return FSSRadomeDMGenerator;
